<script setup>
import {ref, watch} from "vue";
import requestUtil from "@/utils/request";
import {ElMessage} from "element-plus";

const defaultProps = {
  children: 'children',
  label: 'name',
}

const props = defineProps({
  id: {
    type: Number,
    default: -1,
    required: true
  },
  dialogVisible: {
    type: Boolean,
    default: false,
    required: true
  },
  dialogTitle: {
    type: String,
    default: '',
    required: true
  },
})

const form = ref({
  id: -1
})

const treeData = ref([])
const treeRef = ref(null)
const formRef = ref(null)

const checkStrictly = ref(false) // 默认不联动
const checkAll = ref(false) // 全选状态
const expandAll = ref(true) // 展开状态

const initFormData = async (id) => {
  const res = await requestUtil.get('menu/tree/list')
  treeData.value = res.data.msg
  form.value.id = id

  const res2 = await requestUtil.get('role/get/menus?id=' + id)
  treeRef.value.setCheckedKeys(res2.data.msg)
  // 初始化全选状态
  checkAll.value = treeRef.value.getCheckedNodes().length === getAllNodesCount()
}

// 获取树中所有节点数量
const getAllNodesCount = () => {
  let count = 0
  const countNodes = (nodes) => {
    nodes.forEach(node => {
      count++
      if (node.children && node.children.length) {
        countNodes(node.children)
      }
    })
  }
  countNodes(treeData.value)
  return count
}

watch(
    () => props.dialogVisible,
    () => {
      let id = props.id;
      if (id !== -1) {
        initFormData(id)
      }
    }
)

const emits = defineEmits(['update:modelValue', 'initRoleList'])

const handleClose = () => {
  emits('update:modelValue', false)
}

const handleConfirm = async () => {
  const menuIds = treeRef.value.getCheckedKeys();
  let res = await requestUtil.post(
      'role/grant/menu',
      {'id': form.value.id, 'menuIds': menuIds}
  )
  let data = res.data
  if (data.code === 200) {
    ElMessage.success("授权成功")
    emits("initRoleList")
    handleClose()

    let res = await requestUtil.get("user/login");
    let getData = res.data;
    if (getData.code === 200) {
      localStorage.setItem("menuList", JSON.stringify(getData.msg))
    } else {
      ElMessage.error(getData.msg)
    }

  } else {
    ElMessage.error(data.msg)
  }
}

// 全选/全不选切换
const toggleCheckAll = () => {
  if (checkAll.value) {
    treeRef.value.setCheckedNodes(treeData.value)
  } else {
    treeRef.value.setCheckedKeys([])
  }
}

// 展开/折叠切换
const toggleExpandAll = (value) => {
  let treeList = treeData.value;
  for (let i = 0; i < treeList.length; i++) {
    treeRef.value.store.nodesMap[treeList[i].id].expanded = value;
  }
}

// 监听树的选择变化，更新全选状态
const handleCheckChange = () => {
  const checkedCount = treeRef.value.getCheckedNodes().length
  const totalCount = getAllNodesCount()
  checkAll.value = checkedCount === totalCount
}

</script>

<template>
  <el-dialog
      model-value="dialogVisible"
      :title="dialogTitle"
      style="padding: 40px"
      width="400px"
      @close="handleClose"
  >
    <el-form
        ref="formRef"
        :model="form"
        label-width="100px"
    >
      <div style="margin-bottom: 15px; display: flex;">
        <el-checkbox v-model="checkStrictly">父子联动</el-checkbox>
        <el-checkbox v-model="checkAll" @change="toggleCheckAll">全选/取消全选</el-checkbox>
        <el-checkbox v-model="expandAll" @change="toggleExpandAll($event)">展开/折叠</el-checkbox>
      </div>
      <el-tree
          ref="treeRef"
          :data="treeData"
          :props="defaultProps"
          default-expand-all
          show-checkbox
          node-key="id"
          :check-strictly="!checkStrictly"
          @check="handleCheckChange"
      />
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button type="primary" @click="handleConfirm">确认</el-button>
        <el-button @click="handleClose">取消</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style scoped lang="scss">
.dialog-footer {
  display: flex;
  justify-content: flex-end;
}
</style>